package com.ruoyi.order.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import javax.annotation.Resource;

import com.basic.service.impl.BaseServiceImpl;
import com.common.util.SnowFlake;
import com.common.util.TimeUtil;
import com.param.concat.IIdParam;
import com.param.concat.IToExamineParamBySearch;
import com.param.concat.IUpdatePaymentParam;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.order.mapper.MgOrderMapper;
import com.ruoyi.order.domain.MgOrder;
import com.ruoyi.order.service.IMgOrderService;
import com.ruoyi.oss.config.OssConfig;
import com.util.OrderNumberGenerator;
/**
 * 订单Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-12-24
 */
@Service
public class MgOrderServiceImpl extends BaseServiceImpl<Long, MgOrder> implements IMgOrderService {

	private OssConfig config;
	
	
	@Resource
	public void setConfig(OssConfig config) {
		this.config = config;
	}

	Function<IToExamineParamBySearch, Integer>[] functions = new Function[] {
		(p) ->	auditSucess((IToExamineParamBySearch) p),
		(p) ->  auditFail((IToExamineParamBySearch) p)
	};
	
	public MgOrderServiceImpl(MgOrderMapper baseMapper) {
		super(baseMapper);
		// TODO Auto-generated constructor stub
	}

	/**
	 * 查询订单
	 * 
	 * @param id 订单主键
	 * @return 订单
	 */
	@Override
	public MgOrder selectById(Integer id) {
		MgOrder selectById = baseMapper.selectById(id);
		
		String url = "http://".concat(config.getURL());
		
		String translationProofFile = selectById.getTranslationProofFile();
		
		if ( null!= translationProofFile && 0 != translationProofFile.length()) {
			selectById.setTranslationProofFile(url.concat(translationProofFile));
		}
		
		String contractFile = selectById.getContractFile();
		
		if ( null!= contractFile && 0 != contractFile.length()) {
            selectById.setContractFile(url.concat(contractFile));
        }
		
		return selectById;
	}

	/**
	 * 查询订单列表
	 * 
	 * @param mgOrder 订单
	 * @return 订单
	 */
	@Override
	public List<MgOrder> selectList(MgOrder mgOrder) {
		return baseMapper.selectList(mgOrder);
	}
	@Override
	public int cancelTicket(int userId) {
		MgOrderMapper orderMapper = this.getBaseMapper();
		return orderMapper.cancelTicket( userId);
	}
	/**
	 * 新增订单
	 * 
	 * @param mgOrder 订单
	 * @return 结果
	 */
	@Override
	public int insert(MgOrder mgOrder) {
		return baseMapper.insert(mgOrder);
	}

	/**
	 * 修改订单
	 * 
	 * @param mgOrder 订单
	 * @return 结果
	 */
	@Override
	public int update(MgOrder mgOrder) {
		return baseMapper.update(mgOrder);
	}

	/**
	 * 批量删除订单
	 * 
	 * @param ids 需要删除的订单主键
	 * @return 结果
	 */
	@Override
	public int deleteByIds(Integer[] ids) {
		return baseMapper.deleteByIds(ids);
	}

	/**
	 * 删除订单信息
	 * 
	 * @param id 订单主键
	 * @return 结果
	 */
	@Override
	public int deleteById(Integer id) {
		return baseMapper.deleteById(id);
	}

	protected MgOrder[] getEntityObject(int size) {
		return new MgOrder[size];
	}

	protected Class<MgOrder> getEntityClass() {
		return MgOrder.class;
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public <VO> int batchInsert(List<VO> data) {
		// TODO Auto-generated method stub
		return super.batchInsert(data);
	}

	@Override
	protected void afterParseInsert(MgOrder data) {

		data.setOrderSnId(OrderNumberGenerator.generateOrderNumber("ZF") );

//		this.insertProperties(data);

		data.setStatus((byte) 0);

		long time = System.currentTimeMillis() / 1000;

		data.setPayTime(time);
	}

	@Override
	public List<MgOrder> selectList(IIdParam idParam) {
		return this.baseMapper.selectListByUserId(idParam);
	}

	@Override
	public List<MgOrder> selectListByRecharge(IIdParam idParam) {

		MgOrderMapper mapper = this.getBaseMapper();

		return mapper.selectListByUserIdAndRecharge(idParam);
	}

	@Override
	public List<MgOrder> selectListByTab(int[] idParam) {

		MgOrderMapper mapper = this.getBaseMapper();

		return mapper.selectListByTab(idParam);

	}

	@Override
	public List<MgOrder> selectListByEdit(MgOrder order) {

		MgOrderMapper orderMapper = this.getBaseMapper();

		return orderMapper.selectListByEdit(order);

	}

	@Override
	public List<MgOrder> selectListByEditQuery(MgOrder order) {
		MgOrderMapper orderMapper = this.getBaseMapper();

		return orderMapper.selectListByEditQuery(order);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int startParse(Integer id) {

		MgOrder order = new MgOrder();
		
		order.setId(id);
		
		order.setOrderStatus(4);
		
		order.setUserStatus((byte) 4);

		order.setEditStatus((byte) 1);
		
		order.setParseTime(System.currentTimeMillis() / 1000);
		
		return baseMapper.update(order);
	}
	
	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int completeParse(Integer id) {
		MgOrder order = new MgOrder();
		
		order.setId(id);
		
		order.setOrderStatus(6);
		
//		order.setUserStatus((byte) 5);

		order.setEditStatus((byte)  2);
		
		order.setParseTime(System.currentTimeMillis() / 1000);
		
		return baseMapper.update(order);
	}

	@Override
	public int updateAlreadyPay(IUpdatePaymentParam managerParam) {
		MgOrderMapper orderMapper = this.getBaseMapper();
		return orderMapper.updateAlreadyPay(managerParam);
	}

	@Override
	public int updateTeamId(int teamId, int userId) {
		MgOrderMapper orderMapper = this.getBaseMapper();
		return orderMapper.updateTeamId(teamId, userId);
	}

	@Override
	public List<MgOrder> selectOrderByPayManagerId(int[] payManagerId) {
		
		if (0 == payManagerId.length) {
			return new ArrayList<MgOrder>(0);
		}
		
		MgOrderMapper orderMapper = this.getBaseMapper();
		
		return orderMapper.selectOrderByPayManagerId(payManagerId, 0);
	}
	
	@Override
	public List<MgOrder> selectOrderByPayManagerIdForUpdate(int[] payManagerId) {
		
		if (0 == payManagerId.length) {
			return new ArrayList<MgOrder>(0);
		}
		
		MgOrderMapper orderMapper = this.getBaseMapper();
		
		return orderMapper.selectOrderByPayManagerId(payManagerId, 1);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public MgOrder selectOrderForUpdate(int id) {
		MgOrderMapper orderMapper = this.getBaseMapper();
		
		return orderMapper.selectOrderForUpdate(id);
	}

	@Override
	public int toExamineService(IToExamineParamBySearch examineParam) {
		
		Byte status = examineParam.getStatus();
		
		MgOrder selectById = this.selectById(examineParam.getId());
		
		if (null == selectById) {
            return -1;
        }
		
		examineParam.setPayManagerId(selectById.getPayManagerId());
		
		return functions[status].apply(examineParam);
	}
	
	@Transactional(propagation = Propagation.MANDATORY)
	protected int auditSucess(IToExamineParamBySearch examineParam) {
		
		int id = examineParam.getId();
		
		MgOrder order = new MgOrder();
		
		
		order.setId(id);
		
		order.setServiceStatus(examineParam.getServiceType());
		
		order.setEditStatus((byte) 0);
		
		order.setOrderStatus(4);
		
		order.setUserStatus((byte) 4);
		
		return this.update(order);
		
	}

	protected int auditFail(IToExamineParamBySearch examineParam) {
		
		int id = examineParam.getId();
		
		MgOrder selectById = this.selectById(id);
		
		if (null == selectById) {
            throw new IllegalArgumentException("找不到订单");
		}
		
		Integer commentStatus = selectById.getCommentStatus();
		
		Integer orderStatus = 10;
		
		if (null == commentStatus || 1 == commentStatus) {
			
			orderStatus =  11;
		}

		MgOrder order = new MgOrder();
		
		order.setId(id);
		
		order.setServiceStatus(examineParam.getServiceType());
		
		order.setUserStatus((byte) 7);
		
		order.setOrderStatus(orderStatus);
		
		return this.update(order);
	}

	@Override
	public int computerWordSizeByThisMoth(List<Integer> serverIds, long processed) {
		
		MgOrderMapper orderMapper = this.getBaseMapper();
		
//		long timeMillis = System.currentTimeMillis();
		
		
		long firstDayOfMonth = getCurrentMonthStartTime();
		
		Long computerMonthEndTime = TimeUtil.computerMonthEndTime(firstDayOfMonth, "+8", -1) * 1000;
		
		Integer computerWordSizeByThisMoth = orderMapper.computerWordSizeByThisMoth(
				serverIds, processed, firstDayOfMonth / 1000, computerMonthEndTime / 1000);
		
		if (null == computerWordSizeByThisMoth) {
			return 0;
		}
		
		return computerWordSizeByThisMoth;
	}
	
	private long getCurrentMonthStartTime() {
		
		// 获取当前日期  
        LocalDate currentDate = LocalDate.now();  
  
        // 获取当前月份的第一天  
        LocalDate firstDayOfMonth = currentDate.withDayOfMonth(1);  
  
        // 转换为 LocalDateTime，并设置为零时零分零秒  
        LocalDateTime firstDayMidnight = firstDayOfMonth.atStartOfDay();  
  
        // 将 LocalDateTime 转换为 ZonedDateTime（需要时区）  
        ZonedDateTime zonedDateTime = firstDayMidnight.atZone(ZoneId.systemDefault());  
  
        // 将 ZonedDateTime 转换为时间戳（毫秒）  
        return zonedDateTime.toInstant().toEpochMilli();  
		
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public boolean isCancelledByPayManager(long payMangerId) {
		
		List<MgOrder> selectOrderByPayManagerId = this.
				selectOrderByPayManagerIdForUpdate(new int[]{ (int) payMangerId});

		int size = selectOrderByPayManagerId.size();
		if (0 == size) {
			return true;
		}
		
		int cancelNum = 0; 
		
		for (MgOrder order : selectOrderByPayManagerId) {
			
			if (-1 == order.getOrderStatus()) {
                cancelNum++;
            }
		}
		
		return cancelNum == size;
	}
	
//	interface IParseOrder {
//		int apply(IToExamineParamBySearch examineParam, Mg);
//	}
	
	

}
